﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using SiteUnion.Utilities;

namespace SiteUnion.Data
{
   /// <summary>
   ///  用来辅助生成实体对象或实体对象列表
   /// </summary>
   /// <typeparam name="T">目标实体类型</typeparam>
   public class EntityBuilder<T>
   {
      private EntityBuilder(){}

      public static T Read(int oid, ReadCallback callback)
      {
         return callback(oid);
      }

      public static T Execute(string sql, ToEntityCallbackEx callback)
      {
         T t = default(T);
         using (IDataReader dr = DA.ExecuteReader(sql))
         {
            if (dr != null)
            {
               if (dr.Read())
               {
                  t = callback(dr, true);
               }

               dr.Close();
            }
         }

         return t;
      }

      /// <summary>
      /// 
      /// </summary>
      /// <param name="oid"></param>
      /// <param name="tableName"></param>
      /// <param name="callback"></param>
      /// <param name="viewCount"></param>
      /// <returns></returns>
      public static T Read(string oid, string tableName, ToEntityCallbackEx callback,bool viewCount)
      {
         T t = default(T) ;
         using (IDataReader dr = DA.ExecuteReader(SQL.Select(tableName, DF.ALL, " WHERE oid ='" + oid + "'")))
         {
            if (dr != null)
            {
               try 
               {
                  if (dr.Read())
                  {
                     t = callback(dr, true);
                     if (viewCount) IncView(tableName, oid);
                  }
               }
               catch { }finally { dr.Close(); }
            }
         }

         return t;
      }

      public static T Read(string oid, string tableName, ToEntityCallbackEx callback)
      {
         return Read(oid, tableName, callback, false);
      }

      public static T ReadByURL(string urlName, string tableName, ToEntityCallbackEx callback,bool viewCount)
      {
         T t = default(T);
         using (IDataReader dr = DA.ExecuteReader(SQL.Select(tableName, DF.ALL, " WHERE url_name ='" + urlName + "'")))
         {
            if (dr != null)
            {
               try 
               {
                  if (dr.Read())
                  {
                     t = callback(dr, true);
                     if (viewCount) IncViewByURL(tableName, urlName);
                  }
               }
               catch { }
               finally { dr.Close(); }
            }
         }

         return t;
      }

      public static T ReadByURL(string oname, string tableName,ToEntityCallbackEx callback)
      {
         return ReadByURL(oname, tableName, callback, false);
      }

      public static T ReadWhere(string tableName, string whereSQL, ToEntityCallbackEx callback)
      {
         T t = default(T);
         using (IDataReader dr = DA.ExecuteReader(SQL.Select(tableName, DF.ALL, whereSQL)))
         {
            if (dr != null)
            {
               try { if (dr.Read()) t = callback(dr, true); }
               catch { }
               finally { dr.Close(); }
            }
         }
         return t;
      }

      public static IList<T> ReadWhere(string tableName,string fields,string whereSQL, ToEntityCallbackEx callback)
      {
          IList<T> tList = null;
          using (IDataReader dr = DA.ExecuteReader(SQL.Select(tableName, fields, whereSQL)))
          {
             if (dr != null)
             {
                try
                {
                   tList = new List<T>();
                   while (dr.Read())
                   {
                      T t = callback(dr, false);
                      tList.Add(t);
                   }
                }
                catch { }
                finally { dr.Close(); }
             }
          }

         return tList;
      }

      public static IList<T> ReadCount(int count,string tableName,string fields,string whereSQL, ToEntityCallbackEx callback)
      {
         IList<T> tList = null;
         using (IDataReader dr = DA.ExecuteReader(SQL.Select(tableName, "top " + count + " " + fields, whereSQL)))
         {
            if (dr != null)
            {
               try
               {
                  tList = new List<T>();
                  while (dr.Read()) { T t = callback(dr, false); tList.Add(t); }
               }
               catch { }
               finally { dr.Close(); }
            }
         }

         return tList;
      }

      public static IList<T> ReadCount(int count, string tableName, string fields, string whereSQL, ToEntityCallback callback)
      {
         IList<T> tList = null;
         using (IDataReader dr = DA.ExecuteReader(SQL.Select(tableName, "top " + count + " " + fields, whereSQL)))
         {
            if (dr != null)
            {
               try
               {
                  tList = new List<T>();
                  while (dr.Read()) { T t = callback(dr); tList.Add(t); }
               }
               catch { }
               finally { dr.Close(); }
            }
         }

         return tList;
      }

      public static IList<T> Paging(out int recordCount, string tableName, string fields, string sortfield, int start, int end, string orderType, string whereSQL, ToEntityCallbackEx callback)
      {
         IList<T> list = null;

         recordCount = DA.Count(tableName, whereSQL);
         using (IDataReader dr = DA.Paging(tableName, fields, sortfield, start, end, orderType, whereSQL))
         {
            if (dr != null)
            {
               list = new List<T>();
               while (dr.Read()){list.Add(callback(dr, false));}
               dr.Close();
            }
         }

         return list;
      }

      //C////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      public static int Create(string storeProc,string[] values)
      {
         return DA.GetIntValue(CommandType.StoredProcedure,SQL.SPCombine(storeProc, values),null);
      }

      //U///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      public static int Update(string tableName,string[] fields,string[] values,string oid)
      {
         return DA.GetIntValue(CommandType.Text,SQL.Update(tableName, fields, values, "oid=" + oid),null);
      }

      //D//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      public static int Delete(string tableName, string oid)
      { 
         return DA.GetIntValue(CommandType.Text,SQL.Delete(tableName,DF.OID,oid),null);
      }

      //S//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      public static int SetState(string tableName, string oid, string state)
      {
         return DA.GetIntValue(CommandType.Text,SQL.Update(tableName, "state", state, "oid=" + oid),null);
      }

      /// <summary>
      /// 增加点击次数
      /// </summary>
      /// <param name="tableName">表名</param>
      /// <param name="oid">表名</param>
      /// <returns></returns>
      public static int IncView(string tableName, string oid)
      {
         return DA.Inc(tableName, "views", "oid", oid);
      }

      private static int IncViewByURL(string tableName, string urlName)
      {
         return DA.Inc(tableName, "views", "url_name", urlName);
      }

      public delegate T ToEntityCallbackEx(IDataReader dr, bool full);
      public delegate T ToEntityCallback(IDataReader dr);
      public delegate T ReadCallback(int oid);
   }
}
